package predicate

import "server/framework/orm/sql"

type SubQueryOp string

var (
	SubQueryOpAny  SubQueryOp = "any"
	SubQueryOpAll  SubQueryOp = "all"
	SubQueryOpSome SubQueryOp = "some"
)

// SubQuery
/**
SubQuery 常见存在
1. 在where语句中
2. 在from中配合join使用
3. 在select中使用

子查询支持操作符：In、Any、All、Some、Exists
*/
type SubQuery struct {
	QueryBuilder sql.QueryBuilder
	Entity       TableReference
	Alias        string
}

func (s SubQuery) expr() {
}

func (s SubQuery) tableReference() {
}

func (s SubQuery) alias() {}

func (s SubQuery) As(alias string) SubQuery {
	return SubQuery{
		Alias:        alias,
		QueryBuilder: s.QueryBuilder,
		Entity:       s.Entity,
	}
}

func (s SubQuery) Join(tableReference TableReference) JoinBuilder {
	return JoinBuilder{
		left:  s,
		right: tableReference,
		op:    joinOp,
	}
}

func (s SubQuery) LeftJoin(tableReference TableReference) JoinBuilder {
	return JoinBuilder{
		left:  s,
		right: tableReference,
		op:    leftJoinOp,
	}
}

func (s SubQuery) RightJoin(tableReference TableReference) JoinBuilder {
	return JoinBuilder{
		left:  s,
		right: tableReference,
		op:    rightJoinOp,
	}
}

// C subQuery用在from处作为tableReference时，需要传入entity，方便在where处tableReference1.column1 = tableReference2.column2处使用
func (s SubQuery) C(columnName string) Column {
	return Column{
		Entity:     s.Entity,
		ColumnName: columnName,
	}
}

var _ TableReference = SubQuery{}
var _ Alias = SubQuery{}

// SubQueryPredicate 用在where部分,比如 id < some (select * from table where age < 5)
type SubQueryPredicate struct {
	s  SubQuery
	op SubQueryOp
}

func Any(s SubQuery) SubQueryPredicate {
	return SubQueryPredicate{
		s:  s,
		op: SubQueryOpAny,
	}
}

func All(s SubQuery) SubQueryPredicate {
	return SubQueryPredicate{
		s:  s,
		op: SubQueryOpAll,
	}
}

func Some(s SubQuery) SubQueryPredicate {
	return SubQueryPredicate{
		s:  s,
		op: SubQueryOpSome,
	}
}

func Exist(s SubQuery) Predicate {
	return Predicate{
		Right: s,
		Op:    SubQueryOpExists,
	}
}

func (s SubQueryPredicate) expr() {
}
